<?php

class InputValidationHandler {
	
	const E_MAIL_REGEXP = '/^[^0-9][A-z0-9_]+([.][A-z0-9_]+)*[@][A-z0-9_]+([.][A-z0-9_]+)*[.][A-z]{2,4}$/';
	const SOCIAL_SECURITY_REGEXP = '/^[0-9]{10}/';
	const DATE_REGEXP = '/^(\d\d)(\d\d?)(\d\d?)$/'; /* xxxx-xx-xx '/^(\d\d\d\d)-(\d\d?)-(\d\d?)$/'*/   /* alt:  '/^[0-9]{6}' */
	const USER_REGEXP = '/^(?=.{1,15}$)[a-zA-Z][a-zA-Z0-9]*(?: [a-zA-Z0-9]+)*$/';
	const PASS_REGEXP = '/^(?=.{1,15}$)[a-zA-Z][a-zA-Z0-9]*(?: [a-zA-Z0-9]+)*$/';
	const HTML_REGEXP = '</?[a-z][a-z0-9]*[^<>]*>';
	
	/*
	username and pass regexp
	/^(?=.{1,15}$)[a-zA-Z][a-zA-Z0-9]*(?: [a-zA-Z0-9]+)*$/ 
	will allow:
	* 1-15 Characters
    * a-z, A-Z, 0-9, and spaces are acceptable
    * Must begin with a-z or A-Z
    * Cannot end in a space
    * Cannot contain two spaces in a row
	*/

	/*
	 * Socialsecuritynumber
	 */
	public function isValidSocialSecurityNumber($number){
		$number = trim($number);
		
		switch (strlen($number)) {
			case '13': /*19780517-xxxx */
					$number = str_replace("-", "", $number);
					$number = substr($number, 2);
					//Now we have 780517xxxx
				break;
			
			case '12': /*19780517xxxx */
					$number = substr($number, 2);
				break;
			
			case '11': /*780517-xxxx */
					$number = str_replace("-", "", $number);
				break;
				
			case '10': /*780517xxxx */
				//Number is good, keep on rocking...
				break;
			
			default:
				return false;
				break;
		}
		//Check against regexp
		if(preg_match(self::SOCIAL_SECURITY_REGEXP, $number) === false){
			return false;
		}
		else{
			//Calc controll digit, if ok return number else return false
			if($this->calcControllDigit($number)){
				return $number;
			}
			else{
				return false;
			}	
			
		}

	}
	
	public function calcControllDigit($ssn){
		$sum = 0;
 
	    for ($i = 0; $i < strlen($ssn)-1; $i++)
	    {
	        $tmp = substr($ssn, $i, 1) * (2 - ($i & 1)); //växla mellan 212121212
	        if ($tmp > 9) $tmp -= 9;
	        $sum += $tmp;
	    }
	 
	    //extrahera en-talet
	    $sum = (10 - ($sum % 10)) % 10;
	 
	    return substr($ssn, -1, 1) == $sum;
	}
	
	/*
	 * Date
	 *  1999-10-01 =10 tecken
	 *	99-10-01 = 8 tecken
	 *	991001 = 6 tecken
	 */
	public function isValidDate($date){
		$date = trim($date);
		//Check lenght, 6, 8 or 10 is ok, else return false
		switch (strlen($date)) {
			case '6': /* xxxxxx */
				break; 
				
			case '8': /* xx-xx-xx OR 20120101*/
				$date = str_replace("-", "", $date);
				//Still lenght = 8? get rid of first 2 digits
				if(strlen($date) == 8){
					$date = substr($date, 2);
				}
				break; 
				
			case '10': /* xxxx-xx-xx */
				$date = str_replace("-", "", $date);
				$date = substr($date, 2);
				break; 
			
			default:
				return false;
		}	
		//Check agianst our regexp, if false, return it!
		if(preg_match(self::DATE_REGEXP, $date, $matches) === false){
			return false;
		}
		//If true, check if return $matches contains valid dates
		else{
			if(checkdate($matches[2], $matches[3], $matches[1])) {
				return $date;
			}
			else{
				return false;
			}	
		}
		/** bool checkdate  ( int $month  , int $day  , int $year  )Checks the validity of the date. 
		 * A date is considered valid if each parameter is properly defined. 
		*/
	}
	
	/*
	* Messages
	*/
	public function getValidMessageNoTags($message){
		return strip_tags($message);
	}
	
	public function getValidMessage($message){
		$okTags = '<a><img><p>';
		return strip_tags($message, $okTags);
	}
	
	/*
	* User credentials
	*/
	public static function isValidPass($pass){
		return preg_match(self::PASS_REGEXP, $pass);
	}
	
	public static function isValidUser($user){
		return preg_match(self::USER_REGEXP, $user);
	}
	
	public static function isValidEmail($email){
		trim($email);
		return preg_match(self::E_MAIL_REGEXP, $email);
	}
	
	public function isValidNumber($number){
		$number = trim($number);
		return is_numeric($number);
	}
	
	public static function isValidDBPass($pass){
		return true;
	}
	
	public static function isValidDB($DB){
		return true;
		//return preg_match(self::PASS_REGEXP, $DB);
	}
	
	public static function isValidHost($Host){
		return true;
		//return preg_match(self::PASS_REGEXP, $Host);
	}
	
	/**
	* TestArea
	* @return bool
	* Test all methods in InputValidationHandler
	* @todo Implement
	*/
	public function Test(){
		$resultString = "";
		
		//Testar email
		$resultString .= "<p>Testar email, ska ge 4 true och 2 false</p>";
		$testArray = Array('daniel@domain.se','daniel.toll@lnu.se','daniel@student.lnu.se','peter@test.test.nu','peterATTtest.test.nu','peter@test');
		for ($i = 0; $i < count($testArray); $i++) {
			if($this->isValidEmail($testArray[$i])){
				$resultString .= "<p>OK! " . $testArray[$i] ." " . $this->isValidEmail($testArray[$i]) . "</p>";
			}
			else{
				$resultString .= "<p>EJ OK! " . $testArray[$i] . "</p>";
			}
		}
		
		
		//Testar isdate
		$resultString .=  "<p>Testar datum, ska ge 4 true  4 false</p>";
		$testArray = Array('2012-01-15', '01-04-01', '031224', 'abc', '0123', '121401', '20121542', '20120114', ' 01-01-01', '2008-02-29');
		for ($i = 0; $i < count($testArray); $i++) {
			if($this->isValidDate($testArray[$i]) !== false){
				$resultString .= "<p>OK! " . $testArray[$i] ." " . $this->isValidDate($testArray[$i]) . "</p>";
			}
			else{
				$resultString .= "<p>EJ OK! " . $testArray[$i] . "</p>";
			}
		}
		
		//Testar User
		$resultString .=  "<p>Testar anv, ska ge 2 true 4 false</p>";
		$testArray = Array("apa","Pelle Paron","@","","apa ","åäö");
		for ($i = 0; $i < count($testArray); $i++) {
			if($this->isValidUser($testArray[$i])){
				$resultString .= "<p>OK! " . $testArray[$i] ." " . $this->isValidUser($testArray[$i]) . "</p>";
			}
			else{
				$resultString .= "<p>EJ OK! " . $testArray[$i] . "</p>";
			}
		}
		
		//Testar pass
		$resultString .=  "<p>Testar pass, ska ge 2 true 4 false</p>";
		$testArray = Array("apa","Pelle Paron","@","","apa ","åäö");
		for ($i = 0; $i < count($testArray); $i++) {
			if($this->isValidPass($testArray[$i])){
				$resultString .= "<p>OK! " . $testArray[$i] ." " . $this->isValidPass($testArray[$i]) . "</p>";
			}
			else{
				$resultString .= "<p>EJ OK! " . $testArray[$i] . "</p>";
			}
		}
		
		//Testar HTML
		$resultString .=  "<h2>Testar HTML utan script</h2>";
		$testArray = Array('<body>Hej</body>', "<script>alert('Kanon med javascript')</script>", '<p>3</p>', '4', 'KANON');
		for ($i = 0; $i < count($testArray); $i++) {
			$resultString .= "<p> " . $this->getValidMessageNoTags($testArray[$i]) . "</p>";
		}
		
		
		$resultString .=  "<h2>Testar HTML med html</h2>";
		$testArray = Array('<body>Hej</body>', "<script>alert('Kanon med javascript')</script>", '<p>3</p>', '4', "<a href='#'>KANON</a>");
		for ($i = 0; $i < count($testArray); $i++) {
			$resultString .= "<p> " . $this->getValidMessage($testArray[$i]) . "</p>";
		}
		
		//Testar isValidNumber
		$resultString .=  "<p>Testar ValidNumber, 3 true och 3 false</p>";
		$testArray = Array(3, "3", "tre", "en vanlig sträng", "tusen", -1000);
		for ($i = 0; $i < count($testArray); $i++) {
			if($this->isValidNumber($testArray[$i])){
				$resultString .= "<p>OK! " . $testArray[$i] ." " . $this->isValidNumber($testArray[$i]) . "</p>";
			}
			else{
				$resultString .= "<p>EJ OK! " . $testArray[$i] . "</p>";
			}
		}
		
		//Testar isValidSocialSecurityNumber
		$resultString .=  "<p>Testar Personnummer, </p>";
		$testArray = Array('19780517-8888', '060805-2957', '20060805-2957', '2006-08-05-2957', '1234', '123456', '19780517-1945');
		for ($i = 0; $i < count($testArray); $i++) {
			if($this->isValidSocialSecurityNumber($testArray[$i])){
				$resultString .= "<p>OK! " . $testArray[$i] ." " . $this->isValidSocialSecurityNumber($testArray[$i]) . "</p>";
			}
			else{
				$resultString .= "<p>EJ OK! " . $testArray[$i] . "</p>";
			}
		}
		
		echo $resultString;
	}
}
